win32: add more clipboard data checks to avoid crash
authorMarc-André Lureau <marcandre.lureau@gmail.com>
Tue, 22 Apr 2014 17:47:47 +0000 (19:47 +0200)
committerMarc-André Lureau <marcandre.lureau@gmail.com>
Thu, 24 Apr 2014 14:12:07 +0000 (16:12 +0200)
It may happen that the received clipboard data is empty, but
if it's of type image/bmp, gtk+ will crash:

gdk_property_change: 00030AD4 GDK_SELECTION image/bmp REPLACE 8*0 bits:
... delayed rendering
gdk_selection_send_notify_for_display: 00030AD4 CLIPBOARD image/bmp
GDK_SELECTION (no-op)
_gdk_win32_selection_convert_to_dib: 1252003C image/bmp

Program received signal SIGSEGV, Segmentation fault.
0x749a9f40 in msvcrt!memmove () from C:\Windows\syswow64\msvcrt.dll

Thread 1 (Thread 2248.0x1b34):
target=0xc07b) at gdkselection-win32.c:1292
at gdkevents-win32.c:3498
wparam=8, lparam=0) at gdkevents-win32.c:232
message=773, wparam=8, lparam=0)
    at gdkevents-win32.c:263
C:\Windows\syswow64\user32.dll
C:\Users\rugoosse\AppData\Local\virt-viewer\bin\libpangocairo-1.0-0.dll
wparam=0, lparam=-1687549457)
    at gdkevents-win32.c:248
C:\Users\rugoosse\AppData\Local\virt-viewer\bin\libpangocairo-1.0-0.dll

https://bugzilla.gnome.org/show_bug.cgi?id=728745

gdk/win32/gdkproperty-win32.c
gdk/win32/gdkselection-win32.c

index cc0bd25b7cd96250a8d8a628f310f58e20cce719..a2ef3bee45549b70119801542500d1ceeb403edb 100644 (file)
@@ -186,6 +186,12 @@ _gdk_win32_window_change_property (GdkWindow    *window,
       format == 8 &&
       mode == GDK_PROP_MODE_REPLACE)
     {
+      if (type == _image_bmp && nelements < sizeof (BITMAPFILEHEADER))
+        {
+           g_warning ("Clipboard contains invalid bitmap data");
+           return;
+        }
+
       if (type == _utf8_string)
        {
          if (!OpenClipboard (GDK_WINDOW_HWND (window)))
index c2a0893645ab8f99dcb8669822f6076e42fe4100..8c54240782c1c8a6863764573b45cceef0e906a5 100644 (file)
@@ -1285,6 +1285,8 @@ _gdk_win32_selection_convert_to_dib (HGLOBAL  hdata,
 
   if (target == _image_bmp)
     {
+      g_return_val_if_fail (GlobalSize (hdata) >= sizeof (BITMAPFILEHEADER), NULL);
+
       /* No conversion is needed, just strip the BITMAPFILEHEADER */
       HGLOBAL hdatanew;
       SIZE_T size = GlobalSize (hdata) - sizeof (BITMAPFILEHEADER);